<script setup lang="ts">
import { computed, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import type { FormInst, FormItemInst } from 'naive-ui';
import { useMessage, NButton, NCard, NForm, NFormItem, NInput } from 'naive-ui';
import { register } from '../api/user';
import statusCode from '../api/statusCode';
import { listAllError } from '../util/handler';

const router = useRouter();

const formRef = ref<FormInst | null>(null);
const rPasswordFormItemRef = ref<FormItemInst | null>(null);
const message = useMessage();

const formValue = reactive({
  username: '',
  password: '',
  reenteredPassword: ''
});

const validatePasswordPattern = (_: unknown, value: string) =>
        /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/.test(value);

const matchesPasswordPattern = computed(() => validatePasswordPattern(undefined, formValue.password));

const rules = {
  username: {
    required: true,
    message: '请输入用户名',
    trigger: 'blur'
  },
  password: [
    {
      required: true,
      message: '请输入密码',
      trigger: 'input'
    },
    {
      validator: validatePasswordPattern,
      message: '密码必须只包含字母和数字，且在6~18位之间',
      trigger: 'input'
    }
  ],
  reenteredPassword: [
    {
      required: true,
      message: '请再次输入密码',
      trigger: 'input'
    },
    {
      validator: () => formValue.password === formValue.reenteredPassword,
      message: '两次输入的密码不一致',
      trigger: ['input', 'password-input']
    },
  ]
};

const rPasswordIsValid = ref(false);

const handlePasswordInput = () => {
  if (formValue.password) {
    rPasswordFormItemRef.value?.validate({ trigger: 'password-input' })
      .then(() => rPasswordIsValid.value = true)
      .catch(() => rPasswordIsValid.value = false);
  }
};

const formValidate = () => {
  return formRef.value?.validate();
};

const handleRegisterButtonClick = async () => {
  try {
    await formValidate();

    try {
      const resp = await register({
        username: formValue.username,
        password: formValue.password
      });

      if (resp.status === statusCode.SUCCESS) {
        message.success('注册成功');
        router.replace({ path: '/login' });
      } else if (resp.status === statusCode.USERNAME_EXISTS) {
        message.error('用户名已存在');
      } else {
        throw new Error(`错误码 ${resp.status}`);
      }
    } catch (error) {
      message.error("" + error);
    }

  } catch (errors) {
    if (errors instanceof Array) {
      listAllError(errors, message);
    } else {
      throw errors;
    }
  }
};
</script>

<template>
  <n-card>
    <n-form
      :model="formValue"
      :rules="rules"
      :show-require-mark="false"
      ref="formRef"
    >
      <n-form-item
        label="用户名"
        path="username"
      >
        <n-input
          v-model:value="formValue.username"
          placeholder="用户名"
        />
      </n-form-item>
      <n-form-item
        label="密码"
        path="password"
      >
        <n-input
          type="password"
          v-model:value="formValue.password"
          placeholder="密码"
          :maxlength="16"
          @input="handlePasswordInput"
        />
      </n-form-item>
      <n-form-item
        label="重复密码"
        path="reenteredPassword"
        ref="rPasswordFormItemRef"
      >
        <n-input
          :disabled="!matchesPasswordPattern"
          type="password"
          v-model:value="formValue.reenteredPassword"
          placeholder="重复密码"
          :maxlength="16"
          @input="handlePasswordInput"
        />
      </n-form-item>
      <n-form-item>
        <n-button
          :disabled="!rPasswordIsValid"
          @click="handleRegisterButtonClick"
          type="primary"
          attr-type="submit"
        >
          注册
        </n-button>
      </n-form-item>
    </n-form>
  </n-card>
</template>

<style scoped>
</style>
